package com.example.searchjavaapi.parser;


import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

//遍历文档目录，读取所有的html文档内容，把结果解析成行文本文件
//每一行都对应一个文档，每一行都对应文档标题，文档的url，文档的正文（去掉html标签的内容）
//Parser是一个单独的可执行类（带有main方法）
public class Parser {
    //下载好的java-api文档在哪儿
    private static final String INPUT_PATH = "E:\\java\\project\\jdk-8u381-docs-all\\docs\\api";
//    private static final String INPUT_PATH = "/root/javadoc/jdk-8u381-docs-all/docs/api";  //服务器环境
    //预处理模块输出文件存放的目录
    private static final String OUTPUT_PATH = "E:\\raw_data.txt";
//    private static final String OUTPUT_PATH = "/root/javadoc/raw_data.txt";  //服务器环境


    public static void loadIndex() throws IOException {
        FileWriter resultFileWriter = new FileWriter(new File(OUTPUT_PATH));
        //通过main完成整个预处理过程
        //1.枚举出INPUT_PATH下所有html文件（递归）
        ArrayList<File> fileList = new ArrayList<>();
        //递归遍历目录中的文件
        enumFile(INPUT_PATH,fileList);
//        System.out.println(fileList);
        System.out.println("文件数量"+fileList.size());
        //2.针对当前枚举出来的html文件路径进行遍历，依次打开所有文件，读取内容
        //   把内容转换成需要的结构化的数据（DocInfo对象）
        for (File f : fileList){
//            System.out.println("converting"+f.getAbsolutePath()+"...");
            //最终输出的raw_data文件是一个行文本文件，每一行对应一个html文件
            String line = convertLine(f);//每一行的信息
            resultFileWriter.write(line);
        }
        resultFileWriter.close();
        //3.把DocInfo对象写入到最终的输出文件中（OUTPUT_PATH），行文本模式，（格式化转换）


    }

    //此处 raw_data 文件使用行文本文件来表示只是一种方式
    //完全可以使用json或者xml或者其他格式都可以
    private static String convertLine(File f) throws IOException {
        //1.根据f转换成标题
        String title = convertTitle(f);
        //2.根据f转换出url
        String url = convertUrl(f);
        //3.根据f转换出正文
        String content = convertContent(f);
        //4.把这三个文本拼接成一行
        //   \3起到分割符的效果， \3 的AScll值为3的字符，在txt文本中表示不可见字符
        //   类似的，使用\1  \2   \4 都可以
        return title+"\3"+url+"\3"+content+"\n";
//        return title+"\3"+url;
    }

    private static String convertContent(File f) throws IOException {
        /*
        * 将页面中的html标签去掉，\n去掉
        * */
        //1.将文件中的字符一个一个读取出来，然后去掉左右尖括号和\n
        FileReader fileReader = new FileReader(f);
        boolean isContent = true;
        StringBuilder output = new StringBuilder();
        while (true){
            int ret = fileReader.read();
            if (ret==-1){
                //读取完毕
                break;
            }
            char c = (char)ret;
            if (isContent){
                //当前这部分内容是正文
                if (c=='<'){
                    isContent = false;
                    continue;
                }
                if (c=='\n' || c=='\r'){
                    c=' ';
                }
                output.append(c);
            }else{
                if (c=='>'){
                    isContent = true;
                }
            }
        }
        fileReader.close();
        return output.toString();

    }

    private static String convertUrl(File f) {
        //url线上文档对应的url
        //线上文档
        //https://docs.oracle.com/javase/8/docs/api/
        //本地文档

        String part1 = "https://docs.oracle.com/javase/8/docs/api/";
        String part2 = f.getAbsolutePath().substring(INPUT_PATH.length());
        return part1 + part2;

    }


    private static String convertTitle(File f) {
        //把文件名（不是全路径）作为标题就可以了
        String name = f.getName();
        return name.substring(0,name.length()-".html".length());
    }

    //当这个方法递归完毕后，当前inputPath目录下的所有子目录中的。html文件都被加到fileList中了
    private static void enumFile(String inputPath, ArrayList<File> fileList) {
        //递归的把inputPath 对应的全部目录和文件都遍历一遍
        File root = new File(inputPath);
        //listFiles相当于linux上的ls指令
        //把当前目录下所有文件和目录都找到
        File[] files = root.listFiles();
//        System.out.println(Arrays.toString(files));
        //遍历当前这些目录和文件路径，分别处理
        for(File f:files){
            if (f.isDirectory()){
                //如果当前这个f是一个目录，就递归调用enumFile
                enumFile(f.getAbsolutePath(),fileList);
            }else {
                //如果f不是一个目录，看他的文件后缀，如果是。html就把这个文件的对象加入到fileList中
                if (f.getName().contains(".html")){
                    fileList.add(f);
                }
            }
        }

    }



}


















